import { PlusOutlined } from '@ant-design/icons'
import { Select } from 'antd'
import { useEffect, useMemo, useRef, useState } from 'react'
import './style/textareaWithParams.less'

function isIndexInBraces(s, index) {
  if (index < 0 || index >= s.length) return false
  const stack = []
  const braceRanges = []

  for (let i = 0; i < s.length; i++) {
    if (s[i] === '{') {
      stack.push(i)
    } else if (s[i] === '}') {
      if (stack.length > 0) {
        const start = stack.pop()
        braceRanges.push([start, i])
      }
    }
  }

  for (const [start, end] of braceRanges) {
    if (start < index && index < end) return true
  }
  return false
}

function parseToValue(input) {
  const tempDiv = document.createElement('div')
  tempDiv.innerHTML = input
  const traverseNodes = node => {
    let result = ''
    node.childNodes.forEach(child => {
      if (child.nodeType === Node.TEXT_NODE) {
        result += child.textContent
      } else if (child.nodeType === Node.ELEMENT_NODE) {
        result += traverseNodes(child)
      }
    })
    return result
  }
  return traverseNodes(tempDiv)
}

function replacePlaceholders(str) {
  return str.replace(
    /\{\{(.*?)\}\}/g,
    '<span class="textarea-badge" contentEditable="false" onclick="event.stopPropagation(); event.preventDefault();">{{$1}}</span>'
  )
}

function getCursorPosition(editableDiv) {
  let caretOffset = 0
  const doc = editableDiv.ownerDocument || editableDiv.document
  const win = doc.defaultView || doc.parentWindow
  const sel = win.getSelection()
  if (sel.rangeCount > 0) {
    const range = sel.getRangeAt(0)
    const preCaretRange = range.cloneRange()
    preCaretRange.selectNodeContents(editableDiv)
    preCaretRange.setEnd(range.endContainer, range.endOffset)
    caretOffset = preCaretRange.toString().length
  }
  return caretOffset
}

export default function InputWithParamsV2({
  placeholder = '',
  value,
  error = false,
  children = null,
  onChange,
  citeOptions,
  className = '',
  triggerChar = '/',  // 修改默认触发字符为斜杠
  style={},
}) {
  const { inputRef, handleFocus, handleBlur } = usePlaceholder(placeholder)
  const valueRef = useRef(value || '')
  const selectVarRef = useRef(null)
  const [showVarList, setShowVarList] = useState(false)

  const optionsMap = useMemo(() => {
    return citeOptions.reduce((acc, item) => {
        if (item?.value) {
          acc[item.value] = item.value;
        } 
      return acc;
   }, {})
  }, [citeOptions])

  useEffect(() => {
    console.log('optionsMap change', optionsMap)
  }, [citeOptions])

  const currentCursorPosition = useRef(1000)

  const setCurrentCursorPosition = index => {
    currentCursorPosition.current = index
  }

  const handleInput = () => {
    const value = parseToValue(inputRef.current.innerHTML)
    valueRef.current = value
    onChange(value)

    // 检查是否输入了触发字符
    if (value.endsWith(triggerChar)) {
      setShowVarList(true)
      if (selectVarRef.current) {
        selectVarRef.current.focus()
      }
    }
  }

  const getCurrentCursorPosition = () => {
    if (currentCursorPosition.current) return currentCursorPosition.current
    if (currentCursorPosition.current === 0) return 0
    return 1000
  }

  function handleInsertVariable(item, _option) {
    if (inputRef.current && inputRef.current.innerHTML.trim() === placeholder) {
      inputRef.current.innerHTML = ''
      inputRef.current.classList.remove('placeholder')
    }

    const position = getCurrentCursorPosition()
    const currentText = inputRef.current.innerText
    const newSpan = `{{${item}}}`
    let relPosition = position
    let leftText = currentText.slice(0, position)
    let rightText = currentText.slice(position)
    
    // 如果最后一个字符是触发字符（斜杠），则删除它
    if (leftText.endsWith(triggerChar)) {
      leftText = leftText.slice(0, -1)
      relPosition--
    }
    
    if (leftText.endsWith(`}`) && !leftText.endsWith('}}')) {
      relPosition = position + 1
      leftText = currentText.slice(0, relPosition)
    }
    
    const newPosition = relPosition + newSpan.length
    setCurrentCursorPosition(newPosition)

    const newText = leftText + newSpan + rightText
    inputRef.current.innerHTML = replacePlaceholders(newText)

    handleFocus()
    handleInput()
    setTimeout(() => {
      setShowVarList(false)
    }, 10)
  }

  function parseToHTML(input) {
    const html = input
      .replace(/\{\{(.*?)\}\}/g, (a, part) => {
        const error = optionsMap?.[part] === undefined
        const msgZh = optionsMap?.[part] || part
        return `<span class=${
error ? 'textarea-error' : 'textarea-badge'} contentEditable="false" onclick="event.stopPropagation(); event.preventDefault();">{{${msgZh}}}</span>`
      })
    return html
  }

  useEffect(() => {
    inputRef.current.innerHTML = parseToHTML(value || '')
    handleBlur()
  }, [])

  // 添加对 value 的监听
  useEffect(() => {
    if (value !== valueRef.current) {
      inputRef.current.innerHTML = parseToHTML(value || '')
      valueRef.current = value
    }
  }, [citeOptions])

  return (
    <div className={`text-area-with-params-container nodrag relative flex w-full items-center rounded-md border text-sm shadow-sm ${
      error ? 'border-red-500' : 'border-input'
    }`}>
      <div
        ref={inputRef}
        contentEditable
        onInput={handleInput}
        onFocus={handleFocus}
        onBlur={e => {
          const currentPosition = getCursorPosition(inputRef.current)
          const textContent = inputRef.current.innerText
          if (!isIndexInBraces(textContent, currentPosition)) {
            handleBlur()
            setCurrentCursorPosition(currentPosition)
          }
        }}
        onKeyDown={e => {
          if (e.key === triggerChar) {
            const currentPosition = getCursorPosition(inputRef.current)
            const textContent = inputRef.current.innerText
            if (!isIndexInBraces(textContent, currentPosition)) {
              setShowVarList(true)
              setCurrentCursorPosition(currentPosition)
            }
            // 移除 e.preventDefault() 允许斜杠正常输入
          }
        }}
        className={`nowheel panel-custom-richtext no-scrollbar overflow-x-auto overflow-y-hidden whitespace-nowrap border-none px-3 outline-none placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 h-[32px] leading-[32px] ${className}`}
        style={style}
      />
      {showVarList && (
        <div className="absolute left-0 right-0 top-[100%] mt-1 max-h-[200px] overflow-y-auto rounded-md border border-[#d9d9d9] bg-white shadow-md z-50">
          {citeOptions.map((option, index) => (
            <div
              key={index}
              className="flex cursor-pointer justify-between px-3 py-2 text-[14px] hover:bg-[#f5f5f5]"
              onClick={(e) => {
                e.preventDefault()
                e.stopPropagation()
                handleInsertVariable(option.value)
              }}
            >
              <span>{option.group}</span>
              <span className="text-gray-400">{option.name}</span>
            </div>
          ))}
        </div>
      )}
      {children}
    </div>
  )
}

function usePlaceholder(placeholder) {
  const divRef = useRef(null)

  const handleFocus = () => {
    if (divRef.current && divRef.current.innerHTML.trim() === placeholder) {
      divRef.current.innerHTML = ''
      divRef.current.classList.remove('placeholder')
    }
  }

  const handleBlur = () => {
    if (divRef.current && ['<br>', ''].includes(divRef.current.innerHTML.trim())) {
      divRef.current.innerHTML = placeholder
      divRef.current.classList.add('placeholder')
    }
  }

  useEffect(() => {
    if (!placeholder) return
    if (divRef.current) {
      divRef.current.addEventListener('focus', handleFocus)
      divRef.current.addEventListener('blur', handleBlur)

      return () => {
        if (divRef.current) {
          divRef.current.removeEventListener('focus', handleFocus)
          divRef.current.removeEventListener('blur', handleBlur)
        }
      }
    }
  }, [placeholder])

  return { inputRef: divRef, handleFocus, handleBlur }
}
